package com.smartboot.plus.utils;

import java.lang.management.*;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

public class SystemInfoUtil
{


	public static Map<String, Object> getSystemInfo() {
		Map<String, Object> infoMap = new HashMap<>();

		// 获取 JVM 版本
		String jvmVersion = System.getProperty("java.version");
		infoMap.put("version", jvmVersion);

		// 获取线程数
		ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
		int threadCount = threadMXBean.getThreadCount();
		//线程数
		infoMap.put("threadCount", threadCount);

		// 获取内存使用情况

		//内存使用率
		infoMap.put("heapUsagePercentageDouble",getTotalMemoryUsagePercentage());
		//内存大小
		infoMap.put("totalMemoryLimit", getTotalMemoryLimit());
		//堆内存使用
		infoMap.put("heapMemoryUsed", getHeapMemoryUsage());
		//非堆内存
		infoMap.put("nonHeapMemoryUsed", getNonHeapMemoryUsage());
		//物理内存
		infoMap.put("totalPhysicalMemory", getPhysicalMemory());
		//进程 CPU 使用率
		infoMap.put("processCpuLoadDouble", getProcessCpuUsage());
		//CPU使用率
		infoMap.put("systemCpuLoadDouble", getProcessCpuLoadPercentage());
		//CPU 数量
		infoMap.put("cpuCount", Runtime.getRuntime().availableProcessors());
		//cpu架构
		infoMap.put("cpuArchitecture", System.getProperty("os.arch"));
		infoMap.put("vmVersion", jvmVersion);


		return infoMap;
	}

	private static double getProcessCpuLoadPercentage() {
		com.sun.management.OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
		double systemCpuLoad = osBean.getSystemCpuLoad();

		if (systemCpuLoad >= 0) {
			return formatPercentage(systemCpuLoad * 100);
		} else {
			return 0.0;
		}
	}

	private static String getHeapMemoryUsage() {
		MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
		MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
		return formatMemory(heapMemoryUsage.getUsed());
	}

	private static String getNonHeapMemoryUsage() {
		MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
		MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
		return formatMemory(nonHeapMemoryUsage.getUsed());
	}

	private static String getPhysicalMemory() {
		OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
		long totalMemory;
		if (osBean instanceof com.sun.management.OperatingSystemMXBean) {
			totalMemory = ((com.sun.management.OperatingSystemMXBean) osBean).getTotalPhysicalMemorySize();
			return formatMemory(totalMemory);
		} else {
			return "0";
		}
	}

	private static double getProcessCpuUsage() {

		com.sun.management.OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
		return getProcessCpuLoadPercentage(osBean.getProcessCpuLoad());

	}


	public static double getProcessCpuLoadPercentage(Double cpuLoad) {
		if (cpuLoad != null && cpuLoad >= 0) {
			// 转换为百分比并保留两位小数
			return (double) Math.round(cpuLoad * 100); // 保留两位小数
		} else {
			// 如果数据不可用，返回 0.0
			return 0.0;
		}
	}
	// 计算总内存使用率的方法
	public static double getTotalMemoryUsagePercentage() {
		MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
		MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
		MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();

		long totalUsed = heapMemoryUsage.getUsed() + nonHeapMemoryUsage.getUsed();
		long totalMax = heapMemoryUsage.getMax() + nonHeapMemoryUsage.getMax();

		if (totalMax == 0) {
			return 0.0;
		}

		double usagePercentage = (double) totalUsed / totalMax * 100;
		usagePercentage = Math.min(usagePercentage, 100.0);

		return formatPercentage(usagePercentage);
	}

	// 格式化百分比为两位小数
	private static double formatPercentage(double percentage) {
		DecimalFormat df = new DecimalFormat("0.00");
		return Double.parseDouble(df.format(percentage));
	}

	// 获取 JVM 总内存上限（堆内存 + 非堆内存）
	public static String getTotalMemoryLimit() {
		MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
		MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
		long heapMax = heapMemoryUsage.getMax();

		MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
		long nonHeapMax = nonHeapMemoryUsage.getMax();

		long totalMax = heapMax + nonHeapMax;
		return formatMemory(totalMax);
	}

	public static String formatMemory(long bytes) {
		if (bytes < 1024) {
			return bytes + " B";
		} else if (bytes < 1024 * 1024) {
			return String.format("%.2f KB", bytes / 1024.0);
		} else if (bytes < 1024 * 1024 * 1024) {
			return String.format("%.2f MB", bytes / (1024.0 * 1024));
		} else {
			return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
		}
	}
}
